﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ControlLibary
{
    public partial class TestForm : Form
    {
        public TestForm()
        {
            InitializeComponent();

            this.Load += TestForm_Load;

            this.FormClosing += TestForm_FormClosing;

            AddTestGrid();
        }

        private void TestForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            System.Environment.Exit(0); //强制关闭所有线程
        }

        private void TestForm_Load(object sender, EventArgs e)
        {
            Thread thread_main = new Thread(new ThreadStart(() =>
            {
                for (int i = 0; i < dgv.RowCount; i++)
                {
                    Thread thread = new Thread(new ParameterizedThreadStart((obj) =>
                    {
                        int rowIndex = (int)obj;

                        for (int j = 0; j <= 100; j++)
                        {
                            if (this.IsHandleCreated) //避免UI线程关闭了子线程还没推出报错
                                this.BeginInvoke((Action)(() =>
                                {
                                    this.dgv.Rows[rowIndex].Cells[3].Value = j;
                                }));
                            Thread.Sleep(100);
                        }
                    }));

                    thread.Start(i);

                    Thread.Sleep(200);
                }
            }));

            thread_main.IsBackground = true;

            thread_main.Start();
            AddControls();
        }
        DataGridViewEx dgv = null;
        public void AddTestGrid()
        {
            dgv = new DataGridViewEx();

            Type dgvType = dgv.GetType();//首先定义DataGridView的Type类

            //System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic:表示寻找的范围是示例成员以及非公开成员
            PropertyInfo pi = dgvType.GetProperty("DoubleBuffered", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);

            //通过Type类，反射出DoubleBuffered的属性值。
            pi.SetValue(dgv, true, null);//将DoubleBuffered属性值设置为True

            GroupColumn column1 = new GroupColumn();
            column1.Name = "GroupColumn";
            column1.HeaderText = "GroupColumn";
            column1.Width = 150;

            CalendarColumn column2 = new CalendarColumn();
            column2.Name = "CalendarColumn";
            column2.HeaderText = "CalendarColumn";
            column2.Width = 130;

            ColorColumn column3 = new ColorColumn();
            column3.Name = "ColorColumn";
            column3.HeaderText = "ColorColumn";

            column3.Width = 150;

            ProgressColumn column4 = new ProgressColumn();
            column4.Name = "ProgressColumn";
            column4.HeaderText = "ProgressColumn";
            column4.Width = 130;

            CheckBoxColumn column5 = new CheckBoxColumn();
            column5.Name = "CheckBoxColumn";
            column5.HeaderText = "";
            column5.Width = 80;

            ComboBoxColumn column6 = new ComboBoxColumn();
            column6.Name = "ComboBoxColumn";
            column6.HeaderText = "ComboBoxColumn";
            column6.Width = 130;
            column6.ItemsSources = new List<object>() { 1, 1, 2, 3 };


            TextColumn column7 = new TextColumn();
            column7.Name = "TextColumn";
            column7.HeaderText = "TextColumn";
            column7.Width = 100;

            dgv.Columns.AddRange(column1, column2, column3, column4, column5, column6, column7);

            dgv.Dock = DockStyle.Fill;

            panel2.Controls.Add(dgv);

            dgv.RowCount = 500;

            //Add Test Group
            Dictionary<int, List<int>> dics = new Dictionary<int, List<int>>();

            for (int i = 0; i < dgv.RowCount; i++)
            {
                dgv.Rows[i].Cells[0].Value = i;
                if (i % 5 == 0)
                {
                    dics.Add(i, new List<int>());
                }
                else
                {
                    dics[dics.LastOrDefault().Key].Add(i);
                }

                dgv.Rows[i].Cells[column7.Index].Value = string.Format("[{0}]{1}+[{2}]{3}", i, "123", i, "456");
            }

            foreach (var dic in dics)
            {
                (dgv.Rows[dic.Key].Cells[0] as GroupCell).AddChildCellRange(dic.Value);
            }

            //测试线程 用于更新ProgressColumn列的显示
            Thread thread_main = new Thread(new ThreadStart(() =>
            {
                for (int i = 0; i < dgv.RowCount; i++)
                {
                    Thread thread = new Thread(new ParameterizedThreadStart((obj) =>
                    {
                        int rowIndex = (int)obj;

                        for (int j = 0; j <= 100; j++)
                        {
                            if (this.IsHandleCreated) //避免UI线程关闭了子线程还没退出报错
                                this.BeginInvoke((Action)(() =>
                                {
                                    dgv.Rows[rowIndex].Cells[3].Value = j;
                                }));
                            Thread.Sleep(300);
                        }
                    }));

                    thread.Start(i);

                    thread.IsBackground = true;

                    Thread.Sleep(500);
                }
            }));

            thread_main.IsBackground = true;

            thread_main.Start();
        }

        public void AddTrack()
        {
            TrackControl track = new TrackControl();

            track.Dock = DockStyle.Fill;

            track.Size = new Size(50, 50);

            track.Location = new Point(100, 100);

            track.BringToFront();

            panel2.Controls.Add(track);
        }

        SplitContainer sp = new SplitContainer();

        WinTreeView tree = new WinTreeView();

        NativePanel panel1 = new NativePanel();
        NativePanel panel2 = new NativePanel();

        Dictionary<string, Action> controlsDictionary = new Dictionary<string, Action>();

        public void AddControls()
        {
            sp.Dock = DockStyle.Fill;
            sp.SplitterDistance = 25;
            panel1.Dock = DockStyle.Fill;
            panel2.Dock = DockStyle.Fill;
            tree.Dock = DockStyle.Fill;
            tree.BorderStyle = BorderStyle.FixedSingle;
            tree.BackColor = Color.FromArgb(238, 238, 242);
            sp.BackColor = Color.FromArgb(238, 238, 242);
            panel1.Direct = DrawDirect.Bottom | DrawDirect.Left | DrawDirect.Right | DrawDirect.Top;

            this.Controls.Add(sp);
            panel1.Controls.Add(tree);
            sp.Panel1.Controls.Add(panel1);
            sp.Panel2.Controls.Add(panel2);

            TreeNode node_dgv = tree.Nodes.Add("Columns");

            TreeNode node_track = tree.Nodes.Add("TrackControl");

            controlsDictionary.Add(node_dgv.Text, AddTestGrid);

            controlsDictionary.Add(node_track.Text, AddTrack);

            tree.NodeMouseClick += Tree_NodeMouseClick;

            Tree_NodeMouseClick(null, new TreeNodeMouseClickEventArgs(node_dgv, MouseButtons.Left, 1, 0, 0));

            //AddTestGrid();

            //AddTrack();
        }

        private void Tree_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            if (e.Node == null) return;

            if (tree.SelectedNode == e.Node) return;

            var action = controlsDictionary[e.Node.Text];

            //First of all we remove all controls
            for (int i = 0; i < panel2.Controls.Count; i++)
            {
                panel2.Controls.RemoveAt(i--);
            }

            action.Invoke();
        }

    }
}
